package com.netcracker.educenter.filestorage.datasource.dao.file;

import com.netcracker.educenter.filestorage.datasource.dao.FileAccess;
import com.netcracker.educenter.filestorage.datasource.connection.ConnectionPool;
import com.netcracker.educenter.filestorage.datasource.entity.File;
import org.apache.log4j.Logger;

import java.sql.*;
import java.util.ArrayList;

public class FileDAO implements FileAccess {

    private static final Logger log = Logger.getLogger(FileDAO.class);

    private static final String SELECT_USERS_FILES_QUERY = "SELECT * FROM fileslist WHERE userlogin = ? ORDER BY additiontime DESC";
    private static final String INSERT_NEW_FILE_QUERY = "INSERT INTO fileslist " +
            "(filename, filepath, userlogin, additiontime, filesize) " +
            "VALUES (?, ?, ?, ?, ?)";
    private static final String DELETE_FILE_QUERY = "DELETE FROM fileslist WHERE filename = ? AND userlogin = ?";

    @Override
    public ArrayList<File> loadFileList(String userName) {

        ArrayList<File> resultList = new ArrayList<>();
        Connection connection = ConnectionPool.getConnectionPool().getConnection();

        try(PreparedStatement preparedStatement = connection.prepareStatement(SELECT_USERS_FILES_QUERY)) {

            preparedStatement.setString(1, userName);
            ResultSet resultSet = preparedStatement.executeQuery();

            while (resultSet.next()) {
                resultList.add(createFile(resultSet));
            }

        } catch (SQLException e) {
            log.error("Cannot get files list", e);
        }

        ConnectionPool.getConnectionPool().releaseConnection(connection);

        return resultList;
    }

    @Override
    public void add(File file) {

        Connection connection = ConnectionPool.getConnectionPool().getConnection();

        try(PreparedStatement preparedStatement = connection.prepareStatement(INSERT_NEW_FILE_QUERY)) {

            createStatement(preparedStatement, file);
            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            log.error("Cannot add new file", e);
        }

        ConnectionPool.getConnectionPool().releaseConnection(connection);
    }

    @Override
    public void delete(String fileName, String userName) {

        Connection connection = ConnectionPool.getConnectionPool().getConnection();

        try(PreparedStatement preparedStatement = connection.prepareStatement(DELETE_FILE_QUERY)) {

            preparedStatement.setString(1, fileName);
            preparedStatement.setString(2, userName);

            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            log.error(String.format("Cannot delete file %s. User: %s", fileName, userName), e);
        }
    }

    private File createFile(ResultSet resultSet) throws SQLException {

        File file = new File();

        file.setFileName(resultSet.getString("filename"));
        file.setFilePath(resultSet.getString("filepath"));
        file.setUserLogin(resultSet.getString("userlogin"));
        file.setAdditionTime(resultSet.getTimestamp("additiontime"));
        file.setFileSize(resultSet.getInt("filesize"));

        return file;
    }

    private void createStatement(PreparedStatement ps, File file) throws SQLException {

         ps.setString(1, file.getFileName());
         ps.setString(2, file.getFilePath());
         ps.setString(3, file.getUserLogin());
         ps.setTimestamp(4, file.getAdditionTime());
         ps.setLong(5, file.getFileSize());
    }
}

